/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include "mcpy/builtins/string.h"

#include <mc/string.h>
#include <mcpy/exception.h>

#include <cctype>

namespace mcpy {

// 字符串分割（按指定分隔符分割）
mc::array<std::string> str_split(std::string_view str, std::string_view sep) {
    auto result = mc::string::split(str, sep);
    return mc::array<std::string>(std::move(result));
}

// 字符串连接
std::string str_join(const std::vector<std::string>& v, std::string_view delim) {
    return mc::string::join(v, delim);
}

// 字符串连接
std::string str_join(const mc::array<std::string>& v, std::string_view delim) {
    auto impl = v.get_impl();
    if (!impl) {
        return std::string();
    }
    return mc::string::join(*impl, delim);
}

// 查找子串位置
int str_find(std::string_view str, std::string_view sub) {
    auto pos = str.find(sub);
    return pos == std::string_view::npos ? -1 : static_cast<int>(pos);
}

// 计数子串出现次数
int str_count(std::string_view str, std::string_view sub) {
    if (sub.empty()) {
        return 0;
    }

    int         count = 0;
    std::size_t pos   = 0;

    while ((pos = str.find(sub, pos)) != std::string_view::npos) {
        ++count;
        pos += sub.length();
    }

    return count;
}

// 查找子串位置，未找到抛出异常
int str_index(std::string_view str, std::string_view sub) {
    auto pos = str.find(sub);
    if (pos == std::string_view::npos) {
        MC_THROW(mcpy::value_error, "substring not found: ${sub}", ("sub", std::string(sub)));
    }
    return static_cast<int>(pos);
}

// 判断是否全为数字字符
bool str_isdigit(std::string_view str) {
    if (str.empty()) {
        return false;
    }
    for (char c : str) {
        if (!std::isdigit(static_cast<unsigned char>(c))) {
            return false;
        }
    }
    return true;
}

// 判断是否全为字母字符
bool str_isalpha(std::string_view str) {
    if (str.empty()) {
        return false;
    }
    for (char c : str) {
        if (!std::isalpha(static_cast<unsigned char>(c))) {
            return false;
        }
    }
    return true;
}

// 首字母大写，其余小写
std::string str_capitalize(std::string_view str) {
    if (str.empty()) {
        return std::string(str);
    }
    std::string result = mc::string::to_lower(std::string(str));
    result[0]          = std::toupper(static_cast<unsigned char>(result[0]));
    return result;
}

// 每个单词首字母大写
std::string str_title(std::string_view str) {
    std::string result(str);
    bool        new_word = true;

    for (size_t i = 0; i < result.size(); ++i) {
        unsigned char c = result[i];
        if (std::isalpha(c)) {
            if (new_word) {
                result[i] = std::toupper(c);
                new_word  = false;
            } else {
                result[i] = std::tolower(c);
            }
        } else {
            new_word = true;
        }
    }

    return result;
}

// 数字字符串前补零
std::string str_zfill(std::string_view str, int width) {
    if (width <= static_cast<int>(str.length())) {
        return std::string(str);
    }

    size_t fill_count = width - str.length();

    // 处理正负号
    if (!str.empty() && (str[0] == '+' || str[0] == '-')) {
        std::string result;
        result.reserve(width);
        result += str[0];
        result.append(fill_count, '0');
        result.append(str.substr(1));
        return result;
    }

    std::string result;
    result.reserve(width);
    result.append(fill_count, '0');
    result.append(str);
    return result;
}

} // namespace mcpy
